package com.pioneer.web.stock.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pioneer.common.exception.CustomException;
import com.pioneer.web.book.domain.Book;
import com.pioneer.web.book.mapper.BookMapper;
import com.pioneer.web.stock.domain.StoDec;
import com.pioneer.web.stock.domain.StoDecBody;
import com.pioneer.web.stock.mapper.StoDecreaseBodyMapper;
import com.pioneer.web.stock.mapper.StoDecreaseMapper;
import com.pioneer.web.stock.service.IStoDecService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
* @author aom-star@outlook.com
* @description 针对表【sto_decrease】的数据库操作Service实现
* @createDate 2025-05-25 14:07:32
*/
@Service
public class StoDecServiceImpl extends ServiceImpl<StoDecreaseMapper, StoDec>
    implements IStoDecService {
    @Resource
    private StoDecreaseMapper stoDecMapper;

    @Resource
    private BookMapper bookMapper;

    @Resource
    private StoDecreaseBodyMapper stoDecBodyMapper;

    public StoDec select(Long decId) {
        StoDec stoDec = stoDecMapper.selectById(decId);
        if (stoDec == null) {
            throw new CustomException("该损耗单据不存在喵");
        }
        LambdaQueryWrapper<StoDecBody> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoDecBody::getDecreaseId, decId);
        List<StoDecBody> bodyList = stoDecBodyMapper.selectList(queryWrapper);
        stoDec.setBodyList(bodyList);
        return stoDec;
    }

    @Override
    public int insertDec(StoDec dec) {
        List<StoDecBody> bodyList = dec.getBodyList();
        if (bodyList.isEmpty()) {
            throw new CustomException("损耗明细为空喵");
        }
        dec.setStatus("0");
        dealBodyList(bodyList);
        getBaseMapper().insert(dec);
        bodyList.forEach(body -> body.setDecreaseId(dec.getDecreaseId()));
        return stoDecBodyMapper.insertBatch(bodyList);
    }

    @Override
    public int updateDec(StoDec dec) {
        StoDec stoDec = getById(dec.getDecreaseId());
        if (!"0".equals(stoDec.getStatus())){
            throw new CustomException("只有状态为待确认的数据才可以修改");
        }
        List<StoDecBody> bodyList = dec.getBodyList();
        if (CollUtil.isEmpty(bodyList)) {
            throw new CustomException("子信息不能为空");
        }
        dealBodyList(bodyList);
        getBaseMapper().updateById(dec);

        // 删除旧的信息
        LambdaQueryWrapper<StoDecBody> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StoDecBody::getDecreaseId, dec.getDecreaseId());
        stoDecBodyMapper.delete(wrapper);

        return stoDecBodyMapper.insertBatch(bodyList);
    }

    @Override
    public boolean deleteStoDec(List<Long> stoDecIds) {
        List<StoDec> stoDecList = listByIds(stoDecIds);
        if (stoDecList.isEmpty()) {
            throw new CustomException("删除数据不存在喵");
        }
        for (StoDec stoDec : stoDecList) {
            if (!"0".equals(stoDec.getStatus())) {
                throw new CustomException("只有状态为待确认数据才可以删除");
            }
        }
        LambdaQueryWrapper<StoDecBody> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(StoDecBody::getDecreaseId, stoDecIds);
        stoDecBodyMapper.delete(wrapper);
        return removeByIds(stoDecIds);
    }

    @Override
    public boolean approveStoDec(StoDec dec) {
        StoDec stoDec = getById(dec.getDecreaseId());
        if (stoDec == null) {
            throw new CustomException("该数据不存在喵");
        }
        if ("1".equals(stoDec.getStatus())) {
            throw new CustomException("该数据已确认喵");
        }

        // 查询所有损耗明细
        LambdaQueryWrapper<StoDecBody> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StoDecBody::getDecreaseId, dec.getDecreaseId());
        List<StoDecBody> bodyList = stoDecBodyMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(bodyList)) {
            throw new CustomException("没有明细，无法确认喵");
        }

        // 遍历明细，更新库存
        for (StoDecBody body : bodyList) {
            BigDecimal number = body.getNumber();

            Long bookId = body.getBookId();
            Book book = bookMapper.selectById(bookId);

            if (!(book.getStock().compareTo(number) > 0)) {
                throw new CustomException("第" + (bodyList.indexOf(body) + 1) + "行图书库存数据有误喵");
            }

            Book updateBook = new Book();
            updateBook.setId(bookId);
            updateBook.setStock(book.getStock().subtract(number));
            updateBook.setTotal(book.getTotal().subtract(number));
            boolean ret = (bookMapper.updateById(updateBook) > 0);
            if (!ret) {
                throw new CustomException("更新图书失败");
            }
        }

        StoDec update = new StoDec();
        update.setStatus("1");
        update.setDecreaseId(dec.getDecreaseId());
        return updateById(update);
    }

    private void dealBodyList(List<StoDecBody> bodyList) {
        for (int i = 0; i < bodyList.size(); i++) {
            if (bodyList.get(i).getBookId() == null){
                throw new CustomException("图书序号不能为空喵");
            }
            if (bookMapper.selectById(bodyList.get(i).getBookId()) == null) {
                throw new CustomException("第" + (i+1) + "行图书不存在喵");
            }
            if (bodyList.get(i).getNumber() == null) {
                throw new CustomException("数量不能为空喵");
            }
        }
    }
}




